//
//  NetRequestTool.swift
//  HealthMonitoring
//
//  Created by 珠海正杰 on 2018/3/23.
//  Copyright © 2018年 YTYanK. All rights reserved.
//

import UIKit
import Alamofire
import SwiftyJSON
import MBProgressHUD
import Cache
import RKDropdownAlert
//import ParameterEncoding
//import CryptoSwift

public typealias SuccessBlock = (_ response: JSON) -> ()
public typealias FailBlock = (_ errorCode: String, _ msg: String) -> ()

let host = configure.shareConfigure.IP

class NetRequestTool: NSObject {
    var token: String {
        get {
            if UserDefaults.standard.string(forKey: "TOKEN") != nil {
                let tokenStr =  UserDefaults.standard.string(forKey: "TOKEN")!
                return tokenStr
            }else {
                return ""
            }
        }
        set {
            print("NetRequestTool new token : --> \(newValue)")
           UserDefaults.standard.set(newValue, forKey: "TOKEN")   //string(forKey: "TOKEN")
        }
        
    }  // = ""
    var userInfo = JSON()
    var cache: Storage<String>!
    var hud: MBProgressHUD? = nil
    var met: HTTPMethod = .get
    var Content_Type: String = ""    //Content-Type: application/json;charset=utf-8
    var encoding: String = "default"
    var newFun: Bool = false
    
    static let shareInstance: NetRequestTool = {
     
        let instance = NetRequestTool()
        return instance
    }()
    
    class func showLoading(text:String = "加载中...", vc: UIViewController?) {
        let controller =  vc != nil ? vc : UIApplication.shared.keyWindow?.rootViewController
        let hud = MBProgressHUD.showAdded(to: (controller?.view!)!, animated: true)
        hud.label.text = text
        hud.mode = MBProgressHUDMode.indeterminate
        NetRequestTool.shareInstance.hud = hud
    }
    
    class func hideLoading() {
        if let hud = NetRequestTool.shareInstance.hud {
            hud.hide(animated: true)
        }else {
            print("hideloadin errro")
        }
    }
    
    func initCache() {
        let diskConfig = DiskConfig(name: "Zhengjie")
        let memoryConfig = MemoryConfig(expiry: .seconds(3600), countLimit: 10, totalCostLimit: 10)
        
    
        let _storage = try?  Storage(diskConfig: diskConfig, memoryConfig: memoryConfig, transformer: TransformerFactory.forCodable(ofType: String.self))
        self.cache = _storage
    }
    
    
}

extension NetRequestTool {
    
    /** *
        请求方法一
     */
    func netRequest(metString: String, urlString:String, paramsAny:[String: Any]?, this: AnyObject?, finished: @escaping (_ response : [String : Any]?,_ fail: String?, _ error:NSError?)->()){
        let url = host + urlString  
        
        if metString  == "GET" {
            Alamofire.request(url, method: .get, parameters: paramsAny, encoding: JSONEncoding.default, headers: nil)
                .downloadProgress(queue: DispatchQueue.global(qos: .utility)) {
                    Progress in
                    print("Progress: \(Progress.fractionCompleted)")
                }
                .validate { request, response, data in
                    // Custom evaluation closure now includes data (allows you to parse data to dig out error messages if necessary)
                    return .success
                }
                .responseJSON { response in
                    print("\(response.result)")
                    debugPrint(response)
                    if response.result.isSuccess {
                        finished(response.result.value as? [String : Any], nil, nil)
                    }else {
                        finished(nil, nil,response.result.error as NSError?)
                    }
            }
        }else if metString == "POST" {
            
                    Alamofire.request(url, method: .post, parameters: paramsAny, encoding: JSONEncoding.default, headers: nil)
                        .downloadProgress(queue: DispatchQueue.global(qos: .utility)) {
                         Progress in
                            print("Progress: \(Progress.fractionCompleted)")
                        }
                        .validate {
                           request, response, data in
                            return .success
                        }
                        .responseJSON {
                          response in
                             print("\(response.result)")
                            if response.result.isSuccess {
                                finished(response.result.value as? [String: Any], nil, nil)
                            }else {
                               finished(nil, nil, response.result.error as NSError?)
                            }
                        }
        } else {
           //其他类型
            Alamofire.request(url, method: NetRequestTool.shareInstance.met, parameters: paramsAny, encoding: JSONEncoding.default, headers: nil)
                .downloadProgress(queue: DispatchQueue.global(qos: .utility)) {
                    Progress in
                    print("Progress: \(Progress.fractionCompleted)")
                }
                .validate {
                    request, response, data in
                    return .success
                }
                .responseJSON {
                    response in
                    print("\(response.result)")
                    if response.result.isSuccess {
                        finished(response.result.value as? [String: Any], nil, nil)
                    }else {
                        finished(nil, nil, response.result.error as NSError?)
                    }
            }
            
            
        }
    }
    
    /**
      *  登录请求
      */
//    class func login(account: String, code: NSNumber, success:@escaping SuccessBlock, fail:@escaping FailBlock) {
////        if let encrypt = Encrypt.en(text: "\(code)") {
////
////        }
//    }
    /**
        重新登录
      */
//    class func relogin(url: U)
    
    
    /**
       正常请求方法, 请求参数是jsonBody,
       - See 请用 requestForJSON 表单请求
     */
    class func request(url: String, parameters: Parameters, success:@escaping SuccessBlock, fail:@escaping FailBlock, complete: @escaping HMNormalBlock) -> Void {
    
        let _met = NetRequestTool.shareInstance.met
        
        var _par = parameters
        
//        if let token = NetRequestTool.shareInstance.token {
//            _par["token"] = token
//        }
        // 版本号
        if let infoDic = Bundle.main.infoDictionary {
            _par["version"] = infoDic["CFBundleShortVersionString"]
        }
        
        // 头部
        var headers: HTTPHeaders = [
            "en" : "112.90.146.226:9090"
           // "Authorization": "Basic \(NetRequestTool.shareInstance.token)"
        ]
        
        
        //        if (UserDefaults.standard.string(forKey: "TOKEN")?.count)! > 0 { }
            if NetRequestTool.shareInstance.token.count > 0 {
                headers["Authorization"] = NetRequestTool.shareInstance.token //"Basic " + NetRequestTool.shareInstance.token
            }

        if NetRequestTool.shareInstance.Content_Type.count > 0 {
             headers["Content-Type"] = NetRequestTool.shareInstance.Content_Type
             NetRequestTool.shareInstance.Content_Type = ""
        }
        
        
//        var _encoding: ParameterEncoding?
//        if NetRequestTool.shareInstance.encoding == "default" {
//
//            if _met == .get {
//               _encoding = URLEncoding.default
//            }else {
//               _encoding = JSONEncoding.default
//            }
//
//        }
        
            

        // 放密码及账号
//        if let authorizationHeader = Request.authorizationHeader(user: user, password: password) {
//            headers[authorizationHeader.key] = authorizationHeader.value
//        }
        
       var _status = 0
        Alamofire.request(host + url, method: _met, parameters: parameters, headers: headers)
            .validate {
                request, response, data in
                
                _status = response.statusCode
                print("Net response: ------>>\n\(String(describing: request))")
                return .success
            }
            .response {
            response in
            //先运行回调
            complete()
                
//              debugPrint("--调试打印头部",response.response?.allHeaderFields)
                
                
            if let _ = response.error {
                print("Error \(url)")
                fail("\(_status)", "⚠️请求发生错误") //errorCode: String, _ msg: String
                return
            }
                 let data1 = response.data!
                 let utf8Text2 = String(data: data1, encoding: .utf8)
                print("查看返回的json: => \(utf8Text2)")
                if _status == 200 {
                    if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                        let json = JSON(parseJSON: utf8Text)
                        let code = json["code"].intValue // 0 成功, 1 失败
                        let msg = json["msg"].stringValue   //?  json["msg"].stringValue : "未知"
                       
                        if  json["data"].dictionary != nil {
                            let str: String = json["data"]["token"].stringValue
                            if str.count > 0{
                              NetRequestTool.shareInstance.token = str
                              UserDefaults.standard.set(str, forKey: "TOKEN")
                            }
                        }
                        
                        
                        if code == 0 {
//                            if json["data"].isEmpty == false {
                                 success(json)
//                            }else {
//                                success(json)
//                            }
                        }else {
                            print("all error")
                            print("url---->\(host + url)")
                            print("parameters--->\(_par)")
                            print("json--->\(json)")
                            
                            RKDropdownAlert.title("温馨提醒！", message: "⚠️"+msg)
                            fail("\(code)", msg)
                        }
                        
                        
                    }else {
                        print("error")
                        print("\(host + url)")
                        RKDropdownAlert.title("温馨提醒！", message: "⚠️请求发生错误：\(_status)")
//                        fail("\(_status)", "⚠️200码，但是请求错误")
                    }
                }else {
                    RKDropdownAlert.title("温馨提醒！", message: "⚠️请求发生错误：\(_status)")
//                     fail("\(_status)", "⚠️请求错误")
                }
        }

    }
    /// 表单请求
    class func requestForJSON(url: String, parameters: Parameters, success:@escaping SuccessBlock, fail:@escaping FailBlock, complete: @escaping HMNormalBlock) -> Void {
        // 请求方式
        var _met = NetRequestTool.shareInstance.met
      
        // 头部
        var headers: HTTPHeaders = [
            "en" : "112.90.146.226:9090"
        ]
        
        if NetRequestTool.shareInstance.token.count > 0 {
            headers["Authorization"] = NetRequestTool.shareInstance.token //"Basic " + NetRequestTool.shareInstance.token
        }
        
        if NetRequestTool.shareInstance.Content_Type.count > 0 {
            headers["Content-Type"] = NetRequestTool.shareInstance.Content_Type
            NetRequestTool.shareInstance.Content_Type = ""
        }
        
        var _encoding: ParameterEncoding?
        if NetRequestTool.shareInstance.encoding == "default" {
            if _met == .get {
                _encoding = URLEncoding.default
            }else {
                _encoding = JSONEncoding.default
            }
            
        }else {
            _encoding = JSONEncoding.init(options: [])
        }

        var _status = 0
//        if NetRequestTool.shareInstance.newFun == true {
//            var customURL = try! URLRequest(url: host + url, method: _met, headers: headers)
//            customURL.httpMethod = (_met == .post ? "POST" : "GET")
//            customURL.setValue("application/json", forHTTPHeaderField: "Content-Type")
//            customURL.httpBody = try! JSONSerialization.data(withJSONObject: parameters, options: [])
          // customURL = try! _encoding!.encode(customURL, with: parameters)
     
            Alamofire.request(host + url, method: _met, parameters: parameters, encoding: _encoding!, headers: headers)
                .validate {
                    request, response, data in
                    
                    _status = response.statusCode
//                    print("------>>\n\(String(describing: request))")
                    return .success
                }
                .response {
                    response in complete()
                    
               //     debugPrint("--大衣",response.response?.allHeaderFields)
                    
                    
                    if let _ = response.error {
                        print("Error \(url)")
                        fail("\(_status)", "⚠️请求发生错误") //errorCode: String, _ msg: String
                        return
                    }
                    let data1 = response.data!
                    let utf8Text2 = String(data: data1, encoding: .utf8)
                    if _status == 200 {
                        if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                            let json = JSON(parseJSON: utf8Text)
                            let code = json["code"].intValue
                            let msg = json["msg"].stringValue   //?  json["msg"].stringValue : "未知"
                            
                            if  json["data"].dictionary != nil {
                                let str: String = json["data"]["token"].stringValue
                                if str.count > 0{
                                    NetRequestTool.shareInstance.token = str
                                    UserDefaults.standard.set(str, forKey: "TOKEN")
                                }
                            }
                            
                            
                            if code == 0 {
                                success(json)
                            }else {
                                print("all error")
                                print("url---->\(host + url)")
                                print("json--->\(json)")
                                fail("\(code)", msg)
                            }
                            
                            
                        }else {
                            print("error")
                            print("\(host + url)")
                            RKDropdownAlert.title("温馨提示！", message: "⚠️200码，但是请求错误")
//                            fail("\(_status)", "⚠️200码，但是请求错误")
                        }
                    }else {
                        RKDropdownAlert.title("温馨提示！", message: "⚠️ 错误码\(_status)")
//                        fail("\(_status)", "⚠️请求错误")
                    }
            }
        
    }
    

    class func requestMemory(url: String, parameters: Parameters, success:@escaping SuccessBlock, fail:@escaping FailBlock, complete: @escaping HMNormalBlock) -> Void {
        let cache = NetRequestTool.shareInstance.cache
        let key = "\(url)\(parameters)"
        // 如果有缓存，没有就进行请求
        if let jsonStr = try? cache?.object(forKey: key) {
            if let jsonStr = jsonStr {
                let json = JSON(parseJSON: jsonStr)
                complete()
                success(json)
                return
            }
        }
        
        
        request(url: url, parameters: parameters, success: { (json) in
            if let str = json.rawString() {
                let dt = Date().addingTimeInterval(300)
                try? cache?.setObject(str, forKey: key, expiry: Expiry.date(dt))
            }
            success(json)
            
        }, fail: { (error, msg) in
            fail(error,msg)
        }) {
            complete()
        }
        
    }
    
    // 请求，后缓存
    class func requestCache(url: String, parameters: Parameters, success:@escaping SuccessBlock, fail:@escaping FailBlock, complete: @escaping HMNormalBlock) -> Void {
        let cache  = NetRequestTool.shareInstance.cache
        var isResponseFromCache = false
        let key = "\(url)\(parameters)"
        
        if let jsonStr = try? cache?.object(forKey: key) {
            if let jsonStr = jsonStr {
                let json = JSON(parseJSON: jsonStr)
                complete()
                success(json)
                isResponseFromCache = true
            }
        }
        
        request(url: url, parameters: parameters, success: { (json) in
            if let str = json.rawString() {
                try? cache?.setObject(str, forKey: key)
            }
            if !isResponseFromCache {
                success(json)
            }
            
        }, fail: { (error, msg) in
            if !isResponseFromCache {
                fail(error, msg)
            }
        }) {
            if !isResponseFromCache {
                complete()
            }
        }
        
        
    }
    
}


// 这里添加上传图片功能
extension NetRequestTool {
    

    class func upload(url:String, data:[Data],imgName:[String],parameters: Parameters, success: @escaping SuccessBlock, fail:@escaping FailBlock) -> Void {
        
         let _met = NetRequestTool.shareInstance.met
        // 头部
        var _headers: HTTPHeaders = [
            "en" : "112.90.146.226:9090",
            "content-type": "multipart/form-data"
            // "Authorization": "Basic \(NetRequestTool.shareInstance.token)"
        ]
        
        if NetRequestTool.shareInstance.token.count > 0 {
            _headers["Authorization"] = NetRequestTool.shareInstance.token //"Basic " + NetRequestTool.shareInstance.token
        }
        
        
        Alamofire.upload(multipartFormData: { (formData) in
          //  formData.append(, withName: <#T##String#>)
            
            
            for i in 0..<data.count {
                formData.append(data[i], withName: "img", fileName: imgName[i], mimeType: "image/png")
            }
            
           
            
            
        }, usingThreshold: UInt64.init(), to: host + url, method: _met, headers: _headers) { (encodingResult) in
            switch encodingResult {

                case  .success(let upload, _, _):
                  upload.responseJSON(completionHandler: { (response) in
                    debugPrint(response)
                    //statusCode
                    let data1 = response.data!
                    let utf8Text = String(data: data1, encoding: .utf8)
                    let json = JSON(parseJSON: utf8Text!)
                    let code = json["code"].intValue
                    let msg = json["msg"].stringValue   //?  json["msg"].stringValue : "未知"
                    
                    if  json["data"].dictionary != nil {
                        let str: String = json["data"]["token"].stringValue
                        if str.count > 0{
                            NetRequestTool.shareInstance.token = str
                            UserDefaults.standard.set(str, forKey: "TOKEN")
                        }
                    }
                    
                    
                    if code == 0 {
                        success(json["data"])
                    }else {
                        print("all error")
                        print("url---->\(host + url)")
                        print("json--->\(json)")
                        
                        RKDropdownAlert.title("温馨提醒!", message: msg)
                        fail("\(code)", msg)
                    }

                  })
                break
                case .failure(let encodingError):
                    print(encodingError)
                }
            }
        }
        
        
}



